Create an ApiKeyStrategy using passport-headerapikey that reads from the X-API-Key header. Store keys hashed in the database — never plain text. Use a prefix (first 8 chars) to narrow lookups before bcrypt comparison. Build a FlexibleAuthGuard using AuthGuard(['jwt', 'api-key']) to accept either credential type.
Hash API keys with bcrypt before storing — treat them exactly like passwords.
Show the raw key only once at creation — not retrievable after that, same as a password.
Use a prefix for fast lookup narrowing — avoids comparing every key's hash on every request.
Scope API keys to specific permissions and services — avoid granting full access.
Support key rotation — allow creating a new key and provide a grace period before the old one expires.